package fr.sedoo.rbv.geonetwork.request;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.UUID;

import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.io.IOUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;

import fr.sedoo.commons.spring.SpringBeanFactory;
import fr.sedoo.rbv.geonetwork.config.GeonetworkConfig;
import fr.sedoo.rbv.geonetwork.dao.GroupDAO;
import fr.sedoo.rbv.geonetwork.domain.GeonetworkUser;

public class MetadataAddWithoutIdRequest extends AbstractCSWRequest 
{

	private static final String CHARACTER_STRING = "CharacterString";
	private static final String FILE_IDENTIFIER = "fileIdentifier";
	private static final String METADATA_UUID_KEY = "metadata_uuid_key";
	private static final String EXCEPTION_REPORT = "ExceptionReport";
	private String uuid;
	String content="";

	public MetadataAddWithoutIdRequest(String content, GeonetworkConfig config)
	{
		super(config);
		this.content = content;

	}

	public MetadataAddWithoutIdRequest(String content, GeonetworkUser user)
	{
		super(user);
		this.content = content;

	}

	public MetadataAddWithoutIdRequest(String content)
	{
		super();
		this.content = content;

	}

	public boolean execute() throws Exception
	{

		/*
		 * On utilise une requete CSW avec un outputschema par défaut et un ElementSetName de type brief, afin de ne ramener que les informations minimales 
		 */

		Element insertElement = new Element("Insert",cswNamespace);
		Element request = getCSWRootElement();
		request.addContent(insertElement);

		/*
		 * On parse la chaine passé afin de pouvoir ajouter le contenu à la requete
		 */

		SAXBuilder sxb = new SAXBuilder();
		Document document = sxb.build(new ByteArrayInputStream(content.getBytes()));
		Element rootElement = document.detachRootElement();


		// Vérification de l'absence de uuid

		Element uuidElement = rootElement.getChild(FILE_IDENTIFIER, gmdNamespace);
		if (uuidElement != null)
		{
			throw new Exception("uuid already present");
		}
		else
		{
			//On rajoute un UUID
			UUID randomUUID = UUID.randomUUID();
			setUuid(randomUUID.toString());
			Element fileIdentifier = new Element(FILE_IDENTIFIER, gmdNamespace);
			Element characterString = new Element(CHARACTER_STRING, gcoNamespace);
			characterString.setText(getUuid());
			fileIdentifier.addContent(characterString);
			rootElement.addContent(fileIdentifier);
		}

		insertElement.addContent(rootElement);

		String cswURL = getConfig().getCSWPublicationURL();
		PostMethod post = new PostMethod(cswURL);

		try {
			String postData = getString(new Document(request));
			post.setRequestEntity(new StringRequestEntity(postData,"application/xml", UTF8));
			String rawXml = executePostMethod(post);
			if (rawXml.length()>0)
			{
				if (rawXml.contains(EXCEPTION_REPORT))
				{
					if (rawXml.contains(METADATA_UUID_KEY))
					{
						throw new Exception("Existing key - "+rawXml);
					}
					else
					{
						throw new Exception(rawXml);
					}
				}
				else
				{
					CSWRequestResult requestResult = CSWRequestResult.fromXML(rawXml);
					if (requestResult.getTotalInserted() == 1)
					{
						//Temporisation pour s'assurer que Géonetwork s'est mis à jour
						Thread.sleep(1000);


						return true;
					}
					else
					{
						throw new Exception("The insertion hasn't been performed");
					}
				}
			}
			else
			{
				throw new Exception ();
			}
		}

		catch (Exception e)
		{	
			throw new Exception(e);
		}
		finally {
			post.releaseConnection();
		}
	}

	public String getUuid() {
		return uuid;
	}

	public void setUuid(String uuid) {
		this.uuid = uuid;
	}
}
